package com.tarena.lbs.marketing.web.service;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.basic.api.BasicApi;
import com.tarena.lbs.common.passport.enums.Roles;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.marketing.web.dao.repository.ActivityRepository;
import com.tarena.lbs.marketing.web.thread.AuthenticationUtil;
import com.tarena.lbs.pojo.attach.dto.AttachDTO;
import com.tarena.lbs.pojo.attach.param.PicUpdateParam;
import com.tarena.lbs.pojo.attach.query.AttachQuery;
import com.tarena.lbs.pojo.basic.dto.AdminDTO;
import com.tarena.lbs.pojo.marketing.param.ActivityParam;
import com.tarena.lbs.pojo.marketing.po.ActivityPO;
import com.tarena.lbs.pojo.marketing.vo.ActivityVO;
import com.tarena.lbs.pojo.marketing.vo.CouponVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ActivityService {
    @Autowired
    private ActivityRepository activityRepository;
    @DubboReference
    private BasicApi basicApi;
    public PageResult<ActivityVO> activityPage() throws BusinessException {
        //1.拿到userId
        Integer adminId=getUserId();
        //2.拿到businessId
        Integer businessId = getBusinessId(adminId);
        //3.查询活动列表
        List<ActivityPO> pos=getActivityPage(businessId);
        //4.分装分页返回
        return assemblePageResult(pos);
    }

    private PageResult<ActivityVO> assemblePageResult(List<ActivityPO> pos) {
        PageResult<ActivityVO> voPage=new PageResult<>(1,10);
        voPage.setTotal(100L);
        List<ActivityVO> vos=null;
        if (CollectionUtils.isNotEmpty(pos)){
            vos=pos.stream().map(po->{
                ActivityVO vo=new ActivityVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }

    private List<ActivityPO> getActivityPage(Integer businessId) {
        //当前商家 所属的所有活动列表 select * from activity where business_id=#{}
        QueryWrapper<ActivityPO> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("business_id",businessId);
        return activityRepository.list(queryWrapper);
    }

    private Integer getBusinessId(Integer adminId) throws BusinessException {
        //使用 basic服务提供的接口 查询admin
        AdminDTO adminDto = basicApi.getAdminDetail(adminId);
        //断言空
        Asserts.isTrue(adminDto==null,new BusinessException("-2","商家账号不存在"));
        //返回admin详情中的 businessId
        return adminDto.getBusinessId();
    }
    private Integer getUserId() throws BusinessException{
        //不需要判断 角色是否合理
        //拿到认证对象
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        //断言空
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        //返回id
        return userPrinciple.getId();
    }
    private Integer getUserId(Roles role) throws BusinessException {
        //拿到认证对象
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        //断言空
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        //断言角色是否等于入参role
        Asserts.isTrue(userPrinciple.getRole()!=role,new BusinessException("-2","权限不足"));
        //返回id
        return userPrinciple.getId();
    }
    //所有的绑定和关联 在新增时刻 都需要验证存在
    public void activityAdd(ActivityParam param) throws BusinessException {
        //1.认证对象 userId
        Integer adminId=getUserId(Roles.SHOP);
        //2.拿到businessId同时验证admin账号是否存在
        Integer businessId = getBusinessId(adminId);
        //3.新增 封装po数据 写入数据库
        ActivityPO poParam=param2po(param,businessId);
        activityRepository.save(poParam);
        //4.绑定图片 bizId=poParam.getId() bizType=700 活动图片信息
        bindPictures(poParam);
    }
    @DubboReference
    private AttachApi attachApi;
    private void bindPictures(ActivityPO poParam) {
        //1.准备一个 attachApi绑定图片入参list
        List<PicUpdateParam> picParams=null;
        //2.循环切割的imgIds 封装picUpdateParam
        String[] imgIds = poParam.getImgIds().split(",");
        if (imgIds!=null&&imgIds.length>0){
            picParams=Arrays.stream(imgIds).map(imgId->{
                PicUpdateParam param=new PicUpdateParam();
                param.setBusinessId(poParam.getId());
                param.setBusinessType(700);//活动图片类型
                param.setId(Integer.valueOf(imgId));
                return param;
            }).collect(Collectors.toList());
        }
        if (CollectionUtils.isNotEmpty(picParams)){
            //调用图片绑定
            attachApi.batchUpdateBusiness(picParams);
        }
    }

    private ActivityPO param2po(ActivityParam param,Integer businessId) {
        ActivityPO po=new ActivityPO();
        BeanUtils.copyProperties(param,po);
        //1.补充其他字段 当前活动所属商家
        po.setBusinessId(businessId);
        //2.活动状态 0待开始 1已发布 2已过期
        po.setStatus(0);
        //3.管理状态 0启用 1禁用
        po.setEnableStatus(0);
        //4.通用字段 创建时间 修改时间
        Date now=new Date();
        po.setCreateAt(now);
        po.setUpdateAt(now);
        //5.起始时间 结束时间 和优惠券处理方式相同 入参是String字符串"2024-11-20"
        try{
            po.setStartDate(DateUtils.parseDate(param.getStartDate(),"yyyy-MM-dd HH:mm:ss"));
            po.setEndDate(DateUtils.parseDate(param.getEndDate(),"yyyy-MM-dd HH:mm:ss"));
        }catch (Exception e){
            log.error("日期格式数据转化失败",e);
        }
        //6.奖励类型 1优惠券 2积分 数据库写入时 非空校验
        po.setRewardType(1);
        return po;
    }

    /**
     * 当前判断逻辑 有两种可行方案 判断是否是目标人群
     * 第一种方案: marketing调用basice 返回 user绑定标签集合 和人群绑定的标签集合 marketing自己判断
     * 第二种方案: 彻底将userId targetConsumer交给basic 返回true false true就是符合 false不符合
     * @param userId
     * @param activityId
     * @return
     */
    public boolean isTargetConsumer(Integer userId, Integer activityId) {
        //1.activityId 查询活动详情 从活动详情中拿到目标人群的id
        ActivityPO activityPO = activityRepository.getById(activityId);
        Integer groupId=Integer.valueOf(activityPO.getTargetCustomer());
        //2.准备一个 该用户 所属的人群 准备一个远程调用的结果
        //调用 远程 api 获取当前用户的所属人群列表
        List<Integer> userGroupIds=basicApi.getUserGroupIds(userId,activityPO.getBusinessId());
        log.info("当前用户:{},所属人群:{}",userId,userGroupIds);
        //3.判断 活动目标人群 是否在用户所属人群列表中存在 存在 则符合 不存在 则不符合
        if (CollectionUtils.isNotEmpty(userGroupIds)){
            //用户关联的人群列表中 是否存在活动目标人群
            return userGroupIds.contains(groupId);
        }else{
            return false;
        }

    }

    public ActivityVO detail(Integer id) throws BusinessException {
        //1.使用仓储层 查询活动po
        ActivityPO activityPo = activityRepository.getById(id);
        Asserts.isTrue(activityPo==null,new BusinessException("-2","活动不存在"));
        //2.封装vo 考虑到图片数据 从po 拿到imgIds="1,5,19" ==> "http://localhost:9081/static/fileUuid.png"
        ActivityVO vo=new ActivityVO();
        BeanUtils.copyProperties(activityPo,vo);//vo imgUrls没值
        //3.远程盗用dubbo图片服务 拼接活动所需的图片url地址
        List<String> urls=getPicUrls(activityPo);
        vo.setImgPics(urls);
        return vo;
    }
    @Value("${url.prefix}")
    private String urlPrefix;
    private List<String> getPicUrls(ActivityPO activityPo) {
        //1.调用api方法查询到 想查的所有图片dto集合
        /*String imgIds = activityPo.getImgIds();*/
        //2.活动id businessId 活动图片类型 businessType=700
        AttachQuery query=new AttachQuery();
        query.setBusinessId(activityPo.getId());
        query.setBusinessType(700);
        List<AttachDTO> dtos = attachApi.getAttachInfoByParam(query);
        List<String> urls=null;
        if (CollectionUtils.isNotEmpty(dtos)){
            urls=dtos.stream().map(dto->{
                String fileUuid = dto.getFileUuid();
                log.info("读取到图片url:{}",urlPrefix+fileUuid);
                return urlPrefix+fileUuid;
                //http://localhost:9081/static/{fileUuid}
            }).collect(Collectors.toList());
        }
        return urls;
    }

    public List<ActivityPO> getActivitiesByStoreId(Integer storeId) {
        //考虑一下 活动绑定id的字段 shop_ids 值是 这个活动绑定的所有店铺 id拼接 1,3,5
        //FIND_IN_SET(#{storeId},shop_ids)
        return activityRepository.getActivitiesByStoreId(storeId);
    }
}
